指针和常量
使用一个指针时涉及到两个对象:该指针本身和被它所指的对象。将一个指针的声明用const“预先固定”将使那个对象而不是使这个指针成为常量。要将指针本身而不是被指对象声明为常量,我们必须使用声明运算符* const,而不能只用简单的const。例如,
void f1(char* p)
{
char s[] = "Gorm";
const char* pc = s; // 指向常量
pc[3] = 'g'; // 错误❌:pc是指向常量的
pc = p; // ok
char* const cp = s; // 常量指针
cp[3] = 'g'; // ok
cp = p; // 错误❌:cp是常量指针
const char* const cpcp = s; // 到const的const指针
cpc[3] = 'a'; // 错误❌:cpc指向常量
cpc = p; // 错误❌:cpc本身是常量
}
定义常量指针的声明运算符是* const。并没有const * 声明符,所以出现在 * 之前的const是作为基础类型的一部分。例如,
char* const cp; // 到char的const指针
char const* pc; // 到const char的指针
const char* pc2; // 到const char的指针
有人发现从右向左读这种定义很有帮助。例如,“cp是一个const指针到char”,以及“pc2是一个指针指到const char”。
一个某时通过指针访问当做常量的对象,也完全可能在以其他方式访问时被作为变量。对于函数参数而言,这个情况就特别有用。通过将指针参数声明为const,就禁止了这个函数对被指参数的修改。例如,
char* strcpy(char* p, const char* q); // 不能修改*q
你可以将一个变量的地址赋给一个到常量的指针,因为这样做不会造成任何伤害。当然,不能将常量的地址赋给一个未加限制的指针,因为这样将会允许修改该对象的值了。例如,
int a = 1;
const int c = 2;
const int* p1 = &c; // ok
const int* p2 = &a; // ok
int* p3 = &c; // 错误❌:用const int*对int*进行初始化
*p3 = 7; // 试图修改c的值
可以通过对const指针的显式类型转换,明确要求去掉这种限制(10.2.7.1节和15.4.2.1节)。
🔚